/*
  Copyright (c) 2012 Vinícius dos Santos Oliveira

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
  */

/*!
  \page pluginsystem Tufão's plugin system

  \tableofcontents

  When you are developing web applications, usually you are faced with the
  problem of develop applications that will be running for years, without stop.
  Solutions in interpreted languages usually handle this problem by reloading
  the source file each time it changes. In C++, we can achieve a similar
  behaviour through plugins.

  Tufão provides the class Tufao::HttpPluginServer, the application
  _tufao-routes-editor_ and a QtCreator's plugin to facilitate the integration
  of Qt plugins and Tufao::HttpServerRequestRouter.

  \section plugin-hello Understanding by example

  To help you understand the Tufão's plugin system, let's revisit the
  application created in \ref tufao-introduction. This application should be the
  same generated by the _application_ template, under Tufão QtCreator's plugin.

  \subsection plugin-pluginserver The Tufao::HttpPluginServer class

  The Tufao::HttpServerRequestRouter provides a robust request router interface
  and would be useful if we could tell it to use a plugin located in the file
  system as a handler. This is where Tufao::HttpPluginServer enters.

  Tufao::HttpPluginServer implements the Tufao::AbstractHttpServerRequestHandler
  interface, then you can use it as a handler in Tufao::HttpServerRequestRouter.
  Tufao::HttpPluginServer has its own set of mapping rules and handlers, but it
  will load its handlers from plugins.

  In the plugin server created previously, we pass a file in the constructor.
  This is how we set the plugins from Tufao::HttpPluginServer. This file can be
  edited using the tufao-routes-editor tool (see \ref plugin-editor).

  One limitation of Tufao::HttpPluginServer is it that don't know when reload
  the routes file. The Tufão team could add this feature, but this would make
  Tufão less portable. If the Qt framework add the needed API, the Tufão team
  will use it. Until then, you'll need to tell Tufao::HttpPluginServer when to
  reload the config file. This is done invoking the
  Tufao::HttpPluginServer::reloadConfig slot.

  In the previous application, we create a custom handler to invoke the
  Tufao::HttpPluginServer::reloadConfig. We could use a timer, but it may cause
  some troubles in some cases.

  \subsection plugin-user The plugin

  ![](qtcreator_pluginserver.png "The plugin template")

  Enough text! Let's create our plugin. First, you must open QtCreator, go to
  the new project dialog and select the _plugin_ template in the _Tufão Web
  Server project_.

  You'll get the following files:

    - *.pro: The name of this file depends on the name of the project. Tells
      qmake to use the _lib_ _TEMPLATE_ and the _plugin_ _CONFIG_.
    - plugin.h: Defines a class that implements the
      Tufao::AbstractHttpServerRequestHandlerFactory interface, needed by
      Tufao::HttpPluginServer.
    - plugin.cpp: Contains the implementation of Plugin members and uses the
      _Q_EXPORT_PLUGIN2_ macro to export the plugin.
    - requesthandler.h: This is your request handler class. Do whatever you want
      here (but remember to update the plugin.cpp if you change the class or
      file name).
    - requesthandler.cpp: Contains the implementation of RequestHandler members.

  The Tufao::AbstractHttpServerRequestHandlerFactory class is just a
  [factory](https://en.wikipedia.org/wiki/Factory_method_pattern) used by
  Tufao::HttpPluginServer to instantiate new
  Tufao::AbstractHttpServerRequestHandler objects. If you intend to create a
  plugin to be used by Tufao::HttpPluginServer, you must:

    1. Use Qt's plugin system
    2. Implement the Tufao::AbstractHttpServerRequestHandlerFactory interface in
       the plugin class (and don't forget the _Q_INTERFACES_ macro)

  \subsection plugin-editor tufao-routes-editor

  Finally we have:

    - An application supporting plugins
    - A plugin

  The only thing missing here is tell the application to use the plugin we
  created. To do that, we need:

    - Edit the config file used by the plugin server of our application. In the
      previous application, this file is any file named _routes.conf_ placed in
      the application's working dir.
    - Make the application reload its plugins, if the application was already
      running. In the previous application, this is can be done by creating,
      from the same host as the application, a request to the page "/reload"
      (<http://localhost:8080/reload>).

  ![](routes_editor.png "tufao-routes-editor tool")

  To accomplish the final step, the _routes.conf_ file, you must use
  _tufao-routes-editor_ tool. Open the tool, click in "Add handler" and you'll
  have access to the mapping rules. In the field "Plugin location", you must put
  the path of the compiled object file generated from the plugin project.
 */
